#ifndef ESTREE_HPP
#define ESTREE_HPP
#pragma once

#include <string>
#include <vector>
#include <deque>
#include <variant>
#include <optional>
#include <memory>

namespace antlr4
{
	class ParserRuleContext;
}
namespace cyclone::parser
{
	using ull = unsigned long long;

	enum class VariableDeclarationModifierKind
	{
		Let,
		Var,
		Const,
	};

	struct PositionAnnotation
	{
		ull start;
		ull end;
	};

	/**
	 * @brief A node is the parseRule context in antlr4
	 */
	struct Node : PositionAnnotation
	{
		std::string type;
		static PositionAnnotation findRuleStartAndEnd(antlr4::ParserRuleContext *node);
	};
	/**
	 * @brief A terminal node in the parserRule as well as a token
	 */
	struct Terminal : PositionAnnotation
	{
		std::string literal;
	};
	struct TemplateElementValue
	{
		std::optional<std::string> cooked;
		std::string raw;
	};

	struct TemplateElement : Node
	{
		enum TemplateElementSplitter
		{
			Dollar = '$',
			LeftBrace = '{',
			BackQuote = '`',
		};

		bool tail;
		TemplateElementValue value;

		static const std::string TemplateElementType;
		static std::vector<std::shared_ptr<TemplateElement>> formatTemplateElement(antlr4::ParserRuleContext *stringLiteral);
	};

} // namespace cyclone::parser
#endif // ESTREE_HPP